﻿/* HEADER
 * ------
 * © 2010 by Mahdi Khodadadi Fard 
 * modified by:
 * - 
 */
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace Shapes.Misc.Shading
{
    internal sealed class Quadrangle
    {
        private static Dictionary<GraphicsDevice, Quadrangle> Quadrangles = new Dictionary<GraphicsDevice, Quadrangle>();
        internal static Quadrangle Find(GraphicsDevice graphicsDevice)
        {
            if (Quadrangles.ContainsKey(graphicsDevice))
            {
                return Quadrangles[graphicsDevice];
            }
            else
            {
                Quadrangle quad = new Quadrangle(graphicsDevice);
                Quadrangles.Add(graphicsDevice, quad);
                return quad;
            }
        }

        private VertexPositionTexture[] Vertices = new VertexPositionTexture[4];
        private VertexBuffer VertexBuffer = null;

        private GraphicsDevice GraphicsDevice = null;
        RasterizerState rasterState = new RasterizerState();
        RasterizerState lastRasterState;

        DepthStencilState depthStencilState = new DepthStencilState();
        DepthStencilState lastDepthStencilState;


        internal Quadrangle(GraphicsDevice graphicsDevice)
        {
            GraphicsDevice = graphicsDevice;

            VertexBuffer = new VertexBuffer(GraphicsDevice, VertexPositionTexture.VertexDeclaration, 4, BufferUsage.WriteOnly);
            Vertices[0].Position = new Vector3(-1, 1, 0);
            Vertices[1].Position = new Vector3(1, 1, 0);
            Vertices[2].Position = new Vector3(-1, -1, 0);
            Vertices[3].Position = new Vector3(1, -1, 0);

            Vertices[0].TextureCoordinate = new Vector2(0, 0);
            Vertices[1].TextureCoordinate = new Vector2(1, 0);
            Vertices[2].TextureCoordinate = new Vector2(0, 1);
            Vertices[3].TextureCoordinate = new Vector2(1, 1);
            VertexBuffer.SetData<VertexPositionTexture>(Vertices);

            rasterState.CullMode = CullMode.CullCounterClockwiseFace;

            depthStencilState.DepthBufferEnable = false;
            depthStencilState.DepthBufferWriteEnable = false;

        }

        private void Bind()
        {
            lastRasterState = GraphicsDevice.RasterizerState;
            lastDepthStencilState = GraphicsDevice.DepthStencilState;

            GraphicsDevice.RasterizerState = rasterState;
            GraphicsDevice.DepthStencilState = depthStencilState;
            GraphicsDevice.SetVertexBuffer(VertexBuffer);


        }

        private void Draw()
        {
            GraphicsDevice.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 2);
        }

        public void Draw(Effect effect)
        {
            Bind();

            foreach (EffectPass pass in effect.CurrentTechnique.Passes)
            {
                pass.Apply();
                Draw();
            }

            GraphicsDevice.RasterizerState = lastRasterState;
            GraphicsDevice.DepthStencilState = lastDepthStencilState;
        }
    }
}
